from threading import Timer, Thread, Event, Condition
import time


class RepeatingTimer(Timer):
    def __init__(self, interval:float, cond_agent_start:Condition, cond_agent_end:Condition, cond_engine_end:Condition): 
        Thread.__init__(self)
        self._interval = interval  # Agent推演阶段的时长（定值），Game Evolver推演阶段时长可变（由game_envolver.step()方法运行时长决定
        self._finished = Event()
        self._cond_agent_start = cond_agent_start  # Agent推演阶段开始的同步
        self._cond_agent_end = cond_agent_end  # Agent推演阶段结束的同步
        self._cond_engine_end = cond_engine_end  # Game Evolver推演阶段结束的同步
        self.daemon = True

    def run(self):
        while not self._finished.is_set():
            with self._cond_agent_start:
                print("\t--- agent start ---")
                self._cond_agent_start.notify()
            self._finished.wait(self._interval)
            with self._cond_agent_end:
                self._cond_agent_end.notify_all()
            with self._cond_engine_end:
                print("\t--- engine start ---")
                self._cond_engine_end.wait()
        print("\t * 计时器运行结束!")
    
    def stop(self):
        self._finished.set()
        time.sleep(self._interval*3)  # 确保预留出足够长的时间，让计时器循环中程序运行至self._cond_engine_end.wait()处
        with self._cond_engine_end:
            self._cond_engine_end.notify_all()
